package cn.tedu.shoot;

import com.sun.org.apache.bcel.internal.generic.NEW;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class World extends JPanel {
    public static final int WIDTH = 400;
    public static final int HEIGHT = 700;

    public static final int START = 0; //启动状态
    public static final int RUNNING = 1; //运行状态
    public static final int PAUSE = 2; //暂停状态
    public static final int GAME_OVER = 3; //游戏结束状态
    private int state = START; //当前状态

    private Sky sky = new Sky();
    private Hero hero = new Hero();
    private FlyingObject[] flyingObjects = {};
    private Bullet[] bullets = {};


    /**
     * 生成敌人（小敌机 大敌机 小蜜蜂）对象
     */
    public FlyingObject nextOne() {
        Random random = new Random();
        int type = random.nextInt(20);
        if (type < 5) {
            return new Bee();
        } else if (type < 13) {
            return new Airplane();
        } else {
            return new BigAirplane();
        }
    }

    private int enterIndex = 0;//敌机入场计数

    /**
     * 敌人入场
     */
    public void enterAction() {
        enterIndex++;//每10毫秒走一次
        if (enterIndex % 40 == 0) {//每400毫秒走一次
            FlyingObject obj = nextOne();//获取敌人对象
            flyingObjects = Arrays.copyOf(flyingObjects, flyingObjects.length + 1);//扩容
            flyingObjects[flyingObjects.length - 1] = obj;//把新增的放到数组最后一个
        }
    }

    private int shootIndex = 0;//子弹入场计数

    /**
     * 子弹入场
     */
    public void shootAction() {
        shootIndex++;
        if (shootIndex % 10 == 0) {//每300毫秒走一次
            Bullet[] bs = hero.shoot();//获取英雄机发射出来的子弹数组
            bullets = Arrays.copyOf(bullets, bullets.length + bs.length);//扩容
            System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length);
        }
    }

    /**
     * 飞行物移动
     */
    public void stepAction() { //每10毫秒走一次
        sky.step();
        for (int i = 0; i < flyingObjects.length; i++) {
            flyingObjects[i].step();
        }
        for (int i = 0; i < bullets.length; i++) {
            bullets[i].step();
        }
    }

    /**
     * 删除越界的活着删除状态的敌人和子弹
     */
    public void outOfBoundsAction() {//每10毫秒走一次
        for (int i = 0; i < flyingObjects.length; i++) {
            if (flyingObjects[i].isOutOfBounds() || flyingObjects[i].isRemove()) {
                flyingObjects[i] = flyingObjects[flyingObjects.length - 1];//将越界敌人替换为数组的最后一个
                flyingObjects = Arrays.copyOf(flyingObjects, flyingObjects.length - 1);//缩容 将最后一个删掉
            }
        }

        for (int i = 0; i < bullets.length; i++) {
            if (bullets[i].isOutOfBounds() || bullets[i].isRemove()) {
                bullets[i] = bullets[bullets.length - 1];
                bullets = Arrays.copyOf(bullets, bullets.length - 1);
            }
        }
    }

    private int score = 0;

    /**
     * 子弹与敌人的碰撞
     */
    public void bulletBangAction() {//每10毫秒走一次
        for (int i = 0; i < bullets.length; i++) {
            Bullet b = bullets[i];
            for (int j = 0; j < flyingObjects.length; j++) {
                FlyingObject f = flyingObjects[j];
                if (b.isLive() && f.isLive() && f.isHit(b)) {//若都活着 并且撞上了
                    b.goDead();//子弹去死
                    f.goDead();//敌人去死
                    if (f instanceof EnemyScore) { //若被撞对象能得分
                        EnemyScore es = (EnemyScore) f;
                        score += es.getScore();
                    }
                    if (f instanceof EnemyAward) {
                        EnemyAward ea = (EnemyAward) f;
                        int type = ea.getAwardType();
                        switch (type) { //根据奖励类型不同来获取不同的奖励
                            case EnemyAward.FIRE:
                                hero.addFire();
                                break;
                            case EnemyAward.LIFE:
                                hero.addLife();
                                break;
                        }
                    }
                }
            }
        }
    }


    /**
     * 敌人跟英雄机的碰撞
     */
    private void heroBangAction() { //每10毫秒走一次
        for (int i = 0; i < flyingObjects.length; i++) {
            FlyingObject obj = flyingObjects[i];
            if (obj.isLive() && hero.isLive() && hero.isHit(obj)) {
                obj.goDead();
                hero.cutLife();
                hero.clearFire();
            }
        }
    }

    private void checkGameOverAction(){
        if (hero.getLife()<=0){
            state = GAME_OVER;
        }
    }


    /**
     * 启动程序的执行
     */
    public void action() {
        MouseAdapter m = new MouseAdapter() {
            //重写鼠标移动事件
            @Override
            public void mouseMoved(MouseEvent e) {
                if (state == RUNNING){
                    int x = e.getX();//获取鼠标的x坐标
                    int y = e.getY();//获取鼠标的y坐标
                    hero.moveTo(x, y);
                }
            }

            //重写鼠标点击事件
            public void mouseClicked(MouseEvent e){
                switch (state){
                    case START:
                        state = RUNNING; //启动状态时修改为运行状态
                        break;
                    case GAME_OVER:
                        //所有的东西都恢复到刚启动时的一样 清理现场
                        score = 0;
                        sky = new Sky();
                        hero = new Hero();
                        flyingObjects = new FlyingObject[0];
                        bullets = new Bullet[0];
                        state = START;   //游戏结束状态时修改启动状态
                        break;
                }
            }

            //重写鼠标移出事件
            public void mouseExited(MouseEvent e){
                if (state ==RUNNING){
                    state = PAUSE;
                }
            }

            //重写鼠标移入事件
            public void mouseEntered(MouseEvent e){
                if (state == PAUSE){
                    state = RUNNING;
                }
            }
        };//鼠标侦听器
        this.addMouseListener(m);
        this.addMouseMotionListener(m);

        Timer timer = new Timer();//定时器对象
        int intervel = 10; //定时间隔（以毫秒为单位）
        timer.schedule(new TimerTask() {
            @Override
            public void run() {//定时干的事 （每10毫秒走一次）
                if (state == RUNNING){
                    enterAction();//敌人入场
                    shootAction();//子弹入场
                    stepAction();//飞行物移动
                    heroBangAction(); //英雄机跟敌人碰撞
                    bulletBangAction();//子弹与敌人的碰撞
                    outOfBoundsAction();//删除越界的
                    checkGameOverAction();//检测是否为游戏结束状态
                }
                repaint();//重画（重新调用paint（）方法
            }
        }, intervel, intervel);
    }

    public void paint(Graphics g) {
        Images.background.paintIcon(null, g, sky.x, sky.y);
        Images.background.paintIcon(null, g, sky.x, sky.getY1());
        hero.paintImage(g);
        for (int i = 0; i < flyingObjects.length; i++) {
            flyingObjects[i].paintImage(g);
        }
        for (int i = 0; i < bullets.length; i++) {
            bullets[i].paintImage(g);
        }

        g.drawString("玩家得分:" + score, 10, 45);
        g.drawString("剩余命数:" + hero.getLife(), 10, 65);

        switch (state){
            case START:
                Images.start.paintIcon(null,g,0,0);
                break;
            case PAUSE:
                Images.pause.paintIcon(null,g,0,0);
                break;
            case GAME_OVER:
                Images.gameover.paintIcon(null,g,0,0);
                break;
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        World world = new World();
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH, HEIGHT);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);

        world.action();
    }
}
